package com.xy.exam.controller;

import com.xy.exam.entity.User;
import com.xy.exam.service.UserService;
import com.xy.exam.utils.JwtUtil;
import com.xy.exam.utils.ResponseResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * 认证控制器 - 简化版
 * 提供登录、注册和登出功能
 */
@Slf4j
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {

    private final AuthenticationManager authenticationManager;
    private final UserService userService;
    private final JwtUtil jwtUtil;

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public ResponseResult<Map<String, Object>> login(@RequestBody LoginRequest request) {
        try {
            // 认证用户
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(
                            request.getUsername(), 
                            request.getPassword()
                    )
            );
            
            // 设置认证信息
            SecurityContextHolder.getContext().setAuthentication(authentication);
            
            // 获取用户信息
            User user = userService.findUserByUsername(request.getUsername());
            
            // 生成JWT令牌并存入Redis
            String token = jwtUtil.generateToken(user.getUsername());
            
            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            result.put("user", user);
            
            return ResponseResult.success("登录成功", result);
        } catch (AuthenticationException e) {
            log.error("登录失败: {}", e.getMessage());
            return ResponseResult.error("用户名或密码错误");
        }
    }

    /**
     * 用户注册
     */
    @PostMapping("/register")
    public ResponseResult<User> register(@RequestBody RegisterRequest request) {
        // 检查用户名是否已存在
        User existingUser = userService.findUserByUsername(request.getUsername());
        if (existingUser != null) {
            return ResponseResult.error("用户名已存在");
        }
        
        // 创建新用户
        User newUser = new User();
        newUser.setUsername(request.getUsername());
        newUser.setPassword(request.getPassword());
        
        // 注册用户
        User registeredUser = userService.register(newUser);
        if (registeredUser != null) {
            return ResponseResult.success("注册成功", registeredUser);
        } else {
            return ResponseResult.error("注册失败");
        }
    }

    /**
     * 用户登出
     */
    @PostMapping("/logout")
    public ResponseResult<Void> logout() {
        try {
            // 获取当前用户
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.isAuthenticated()) {
                String username = authentication.getName();
                // 从Redis中删除token
                jwtUtil.invalidateToken(username);
            }
            
            // 清除安全上下文
            SecurityContextHolder.clearContext();
            
            return ResponseResult.success("登出成功", null);
        } catch (Exception e) {
            log.error("登出失败: {}", e.getMessage());
            return ResponseResult.error("登出失败");
        }
    }
    /*数据传输: 在控制器方法中使用 @RequestBody 注解将客户端发送的 JSON 数据自动转换为这些对象
      数据封装: 将请求参数组织成有意义的对象，而不是使用散乱的参数
      代码清晰: 使控制器方法的参数列表更简洁、更有意义*/

    /**
     * 登录请求DTO
     */
    public static class LoginRequest {
        private String username;
        private String password;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    /**
     * 注册请求DTO
     */
    public static class RegisterRequest {
        private String username;
        private String password;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }
} 